#include "CudaResultAnalysis.cuh"

#include <exception>

#include <thrust/device_ptr.h>
#include <thrust/device_vector.h>
#include <thrust/extrema.h>

#include <utils/Print.h>

using namespace solar::cuda;

void CudaResultAnalysis::analyzeResultData(float* d_data, float& max_flux, float& sum_energy,
                                           int2& max_location) const
{
    thrust::device_ptr<float> dev_ptr(d_data);
    float pixel_sum = thrust::reduce(dev_ptr, dev_ptr + size_t(resolution_.x * resolution_.y),
                                     (float)0, thrust::plus<float>());

    // float pixel_max = thrust::reduce(dev_ptr, dev_ptr + size_t(resolution.x * resolution.y),
    // (float)0, thrust::max_element<float>());
    thrust::device_vector<float>::iterator d_it =
        thrust::max_element(dev_ptr, dev_ptr + size_t(resolution_.x * resolution_.y));

    int max_index = d_it - (thrust::device_vector<float>::iterator)dev_ptr;
    float pixel_max = *d_it;

    double pixel_area = 0;
    switch (receiver_type_)
    {
    /*
        0-- rect
        1-- cylinder
        2-- refined rect
        3--refined cylinder
        4--multi panel
    */
    case 0:
        [[fallthrough]];
    case 1:
        pixel_area = pixel_ * pixel_;
        break;
    case 2:
    case 3:
    case 4:
        solar::println(
            "CudaResultAnalysis::analyzeResultData()::not sure how to calculate pixel area");
        pixel_area = pixel_ * pixel_;
        break;
    }

    max_flux = pixel_max / 1000.0;              // 单位：KW/m2
    sum_energy = pixel_sum * pixel_area / 1000; // 单位：KW
    // d_data是倒过来存的，0行是接收器顶部，resolution.x-1行是接收器底部,这里的max_y正方向朝上
    int max_x = max_index % resolution_.x;
    int max_y = resolution_.y - 1 - max_index / resolution_.x;
    max_location = make_int2(max_x, max_y);

    printf("in CudaResultAnalysis: pixel_sum = %f, max_index = %d, pixel_max = %f\n", pixel_sum,
           max_index, pixel_max);
}
